package dragon.core.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import dragon.core.exception.ExceptionHandler;
import dragon.core.util.StringUtils;

public class XMLHandler {

	public static final String TAG_NAME_KEY = "tagName";

	private static final String ID_KEY = "id";

	private static final String P_TAG_NAME_KEY = "pTagName";

	private static final String P_ID_KEY = "pID";

	private static final String CHILD_TAG_NAME_KEY = "childTagName";

	public static final String CHILDREN_KEY = "children";

	public static final String TEXT_CONTENT = "textContent";

	/**
	 * 默认根节点标签
	 */
	private static final String defaultRootTagName = "root";

	/**
	 * DocumentBuilder对象，用于创建，解析Document对象
	 */
	private static DocumentBuilder db = null;

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(XMLHandler.class);

	/**
	 * XML错误处理类
	 */
	static class XMLErrorHandler implements ErrorHandler {
		@Override
		public void error(SAXParseException exception) {
			logger.error("Error: at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber(), exception);
			exception.printStackTrace(System.err);
		}

		@Override
		public void fatalError(SAXParseException exception) {
			logger.error("Error: at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber(), exception);
			exception.printStackTrace(System.err);
		}

		@Override
		public void warning(SAXParseException exception) {
			logger.error("Error: at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber(), exception);
			exception.printStackTrace(System.err);
		}
	}

	/**
	 * 创建DocumentBuilder<br>
	 * 调用该类的任何方法之前，需要保证至少调用一次本方法
	 * 
	 * @param validate
	 *            是否校验XML文件
	 * @return DocumentBuilder 对象
	 * @throws ParserConfigurationException
	 */
	private static DocumentBuilder createDocumentBuilder(boolean validate) throws ExceptionHandler {
		if (db == null) {
			DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
			f.setValidating(validate);
			try {
				db = f.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				throw new ExceptionHandler(e);
			}
			db.setErrorHandler(new XMLErrorHandler());
		}
		return db;
	}

	/**
	 * 解析XML文件，获取Document对象
	 * 
	 * @param filePath
	 *            XML文件路径
	 * @param closeStream
	 *            是否关闭文件流
	 * @return Document 对象
	 * @throws ExceptionHandler
	 */
	private static Document getDocument(String filePath, boolean closeStream) throws ExceptionHandler {
		File file = new File(filePath);
		if (!file.exists()) {
			return null;
		}
		try {
			return getDocument(new FileInputStream(file), closeStream);
		} catch (FileNotFoundException e) {
			throw new ExceptionHandler(e);
		}
	}

	/**
	 * 解析XML文件，获取Document对象
	 * 
	 * @param in
	 *            XML文件流
	 * @param closeStream
	 *            是否关闭文件流
	 * @return Document 对象
	 * @throws ExceptionHandler
	 */
	private static Document getDocument(InputStream in, boolean closeStream) throws ExceptionHandler {
		if (db == null) {
			XMLHandler.createDocumentBuilder(false);
		}

		Document doc = null;
		try {
			doc = db.parse(in);
			if (closeStream) {
				in.close();
			}
		} catch (SAXException e) {
		} catch (IOException e) {
		}
		return doc;
	}

	/**
	 * 解析XML文件数据
	 * 
	 * @param filePath
	 *            XML文件路径
	 * @param tagName
	 *            标签名称
	 * @param idValue
	 *            属性ID值，如果此参数为Null，则返回所有指定标签的节点
	 * @param closeStream
	 *            是否关闭文件流
	 * @return
	 * @throws ExceptionHandler
	 */
	public static List<Map<String, Object>> readXML(String filePath, String tagName, String idValue, boolean closeStream) throws ExceptionHandler {
		File file = new File(filePath);
		if (!file.exists()) {
			throw new ExceptionHandler("未发现文件：" + filePath);
		}
		try {
			return readXML(new FileInputStream(file), tagName, idValue, closeStream);
		} catch (FileNotFoundException e) {
			throw new ExceptionHandler(e);
		}
	}

	/**
	 * 解析XML文件数据
	 * 
	 * @param in
	 *            XML文件流
	 * @param validate
	 *            是否校验XML文件
	 * @param tagName
	 *            标签名称
	 * @param idValue
	 *            属性ID值，如果此参数为Null，则返回所有指定标签的节点
	 * @param closeStream
	 *            是否关闭文件流
	 * @return List<Map> <br>
	 *         每个节点返回一个Map对象，该Map对象包含了节点下的子节点数据
	 * @throws ExceptionHandler
	 */
	public static List<Map<String, Object>> readXML(InputStream in, String tagName, String idValue, boolean closeStream) throws ExceptionHandler {
		try {
			if (in.available() == 0) {
				in.reset();
			}
			Document document = getDocument(in, closeStream);
			if (document != null) {
				return findNodes(document, tagName, idValue);
			} else {
				return null;
			}
		} catch (Exception ex) {
			throw new ExceptionHandler(ex);
		}
	}

	/**
	 * 根据标签名称超找节点
	 * 
	 * @param document
	 *            Document对象
	 * @param tagName
	 *            标签名称
	 * @param idValue
	 *            属性ID值，如果此参数为Null，则返回所有指定标签的节点
	 * @return
	 */
	private static List<Map<String, Object>> findNodes(Document document, String tagName, String idValue) {
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		if (!StringUtils.isEmpty(tagName)) {
			// 从指定节点查找
			Node[] nodes = findNode(document, tagName, idValue);
			if (nodes != null) {
				for (Node node : nodes) {
					result.add(parseNode(node));
				}
			}
		} else {
			// 从根节点查找
			Node rootNode = document.getFirstChild();
			result.add(parseNode(rootNode));
		}
		return result;
	}

	/**
	 * 解析节点
	 * 
	 * @param node
	 *            Node 对象
	 * @return Map节点数据，包含子级节点数据
	 */
	private static Map<String, Object> parseNode(Node node) {

		Map<String, Object> nodeMap = new LinkedHashMap<String, Object>();
		nodeMap.put(TAG_NAME_KEY, node.getNodeName());
		// 节点属性
		NamedNodeMap attributes = node.getAttributes();
		if (attributes != null) {
			for (int j = 0; j < attributes.getLength(); j++) {
				Node n = attributes.item(j);
				nodeMap.put(n.getNodeName(), n.getNodeValue());
			}
		}

		// 节点下的直接内容
		if (node.getFirstChild() != null) {
			nodeMap.put(TEXT_CONTENT, node.getFirstChild().getTextContent().trim());
		}

		// 子节点
		List<Map<String, Object>> childrenList = new ArrayList<Map<String, Object>>();
		NodeList children = node.getChildNodes();
		if (children != null) {
			for (int k = 0; k < children.getLength(); k++) {
				if (!"DeferredTextImpl".equals(children.item(k).getClass().getSimpleName())) {
					childrenList.add(parseNode(children.item(k)));
				}
			}
		}
		nodeMap.put(CHILDREN_KEY, childrenList);

		return nodeMap;
	}

	/**
	 * 打印特定结构的Map对象
	 * 
	 * @param map
	 *            数据
	 * @param level
	 *            层级，调用时传入0
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String toString(Map<String, Object> map, int level) {
		StringBuilder sb = new StringBuilder();
		Set<String> set = map.keySet();
		Iterator<String> it = set.iterator();
		boolean printPrefix = true;
		while (it.hasNext()) {
			String key = it.next();
			if (!CHILDREN_KEY.equals(key)) {
				if (printPrefix) {
					for (int i = 0; i < level; i++) {
						sb.append("------");
						printPrefix = false;
					}
				}
				sb.append(key).append("=").append(map.get(key)).append("\t");
			} else {
				sb.append("\n");
				List<Map<String, Object>> list = (List<Map<String, Object>>) map.get(key);
				for (Map<String, Object> m : list) {
					sb.append(toString(m, level + 1));
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 创建XML文件
	 * 
	 * @param filePath
	 *            XML文件路径
	 * @param data
	 *            数据对象
	 * @throws ExceptionHandler
	 */
	public static void createXML(String filePath, Map<String, Object> data) throws ExceptionHandler {

		if (data == null) {
			throw new ExceptionHandler("待写入的数据对象为null！");
		}

		if (StringUtils.isEmpty(filePath)) {
			throw new ExceptionHandler("请提供XML文件路径！");
		}

		if (db == null) {
			XMLHandler.createDocumentBuilder(false);
		}

		try {

			// Step 1 判断目标xml文件是否存在
			boolean isDocumentNew = false;// 标记文档是否新创建
			Document document = getDocument(filePath, true);
			if (document == null) {
				document = db.newDocument();// 目标文件不存在，新建Document对象
				isDocumentNew = true;
			}

			if (logger.isDebugEnabled()) {
				if (isDocumentNew) {
					logger.debug("新创建的文档");
				} else {
					logger.debug("已存在的文档");
				}
			}

			// Step 2 创建(设置)根节点
			Node rootNode = null;

			String tagName = data.get(TAG_NAME_KEY) != null ? (String) data.get(TAG_NAME_KEY) : null;
			String id = data.get(ID_KEY) != null ? (String) data.get(ID_KEY) : null;

			String pTagName = data.get(P_TAG_NAME_KEY) != null ? (String) data.get(P_TAG_NAME_KEY) : null;
			String pID = data.get(P_ID_KEY) != null ? (String) data.get(P_ID_KEY) : null;

			if (isDocumentNew) {
				// Step 2-1 如果文件是新创建的，则需要创建根节点
				String rootTagName = !StringUtils.isEmpty(pTagName) ? pTagName : !StringUtils.isEmpty(tagName) ? tagName : defaultRootTagName;
				rootNode = document.createElement(rootTagName);
				document.appendChild(rootNode);
				if (logger.isDebugEnabled()) {
					logger.debug("新的文档，创建根节点：" + rootTagName);
				}
			} else {
				// 否则，需要根据设置的信息查找根节点，当查找不到时，默认使用文档的根节点(不存在，需要重新创建)

				// Step 2-2-1 获得文档的根节点，不存在，则创建
				Node documentRootNode = document.getFirstChild();
				if (documentRootNode == null) {
					documentRootNode = document.createElement(defaultRootTagName);
					document.appendChild(documentRootNode);
					if (logger.isDebugEnabled()) {
						logger.debug("已存在的文档，创建新的文档ROOT：" + defaultRootTagName);
					}
				}

				// Step 2-2-2 根据设置的父节点信息查找起始节点
				boolean isParentExist = false;// 标记是否存在父节点
				if (!StringUtils.isEmpty(pTagName)) {
					Node[] nodes = findNode(document, pTagName, pID);
					if (nodes != null) {
						if (nodes.length == 1) {
							rootNode = nodes[0];
							isParentExist = true;
							if (logger.isDebugEnabled()) {
								logger.debug("找到父节点");
							}
						} else if (nodes.length > 1) {
							throw new ExceptionHandler(String.format("父节点不唯一：TagName:%s,ID:%s", pTagName, pID));
						}
					}
					// 设置了父节点信息，但是父节点不存在，需要创建该父节点
					if (!isParentExist) {
						throw new ExceptionHandler("未找到指定的父节点！");
					}
				}

				// Step 2-2-3 根据设置的当前节点信息查找起始节点
				if (!isParentExist) {
					boolean isSelfExist = false;// 标记是否存在自身节点
					if (!StringUtils.isEmpty(tagName)) {
						Node[] nodes = findNode(document, tagName, id);
						if (nodes != null) {
							if (nodes.length == 1) {
								rootNode = nodes[0];
								isSelfExist = true;
								if (logger.isDebugEnabled()) {
									logger.debug("找到自身节点");
								}
							} else if (nodes.length > 1) {
								throw new ExceptionHandler(String.format("节点不唯一：TagName:%s,ID:%s", tagName, id));
							}
						}

						if (!isSelfExist) {
							// 创建新的节点并将其设置为起始节点
							Element element = document.createElement(tagName);

							Set<String> set = data.keySet();
							Iterator<String> it = set.iterator();
							while (it.hasNext()) {
								String key = it.next();
								if (isKeyWord(key)) {
									continue;
								}
								String value = data.get(key) != null ? (String) data.get(key) : null;

								element.setAttribute(key, value);
							}

							documentRootNode.appendChild(element);
							rootNode = element;
							if (logger.isDebugEnabled()) {
								logger.debug("已存在的文档，创建根节点：" + tagName);
							}
						}
					} else {
						throw new ExceptionHandler("数据不合法，未提供父节点信息，且未提供新节点标签名称，无法创建起始节点！");
					}
				}

			}

			// 创建内容
			createXMLContent(document, rootNode, data);

			// 将变更写入文件
			transform(document, filePath);

		} catch (TransformerFactoryConfigurationError e) {
			throw new ExceptionHandler(e);
		}
	}

	/**
	 * 创建XML文件内容
	 * 
	 * @param document
	 *            Document 对象
	 * @param rootNode
	 *            根节点
	 * @param data
	 *            数据对象
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	private static void createXMLContent(Document document, Node rootNode, Map<String, Object> data) throws ExceptionHandler {

		// 子节点TagName
		String childTagName = data.get(CHILD_TAG_NAME_KEY) != null ? (String) data.get(CHILD_TAG_NAME_KEY) : null;

		// 子节点数据
		List<Map<String, Object>> children = data.get(CHILDREN_KEY) != null ? (List<Map<String, Object>>) data.get(CHILDREN_KEY) : null;
		if (children == null) {
			return;
		}

		for (Map<String, Object> map : children) {

			String tagName = map.get("tagName") != null ? (String) map.get("tagName") : childTagName;

			if (StringUtils.isEmpty(tagName)) {
				if (logger.isDebugEnabled()) {
					logger.debug("创建节点失败，缺少标签！" + map);
				}
				continue;
			}

			// 先查找节点是否存在
			Element element = null;
			if (logger.isDebugEnabled()) {
				logger.debug("findNode:" + tagName + "\t" + map.get(ID_KEY));
			}
			Node[] nodes = findNode(rootNode, tagName, (String) map.get(ID_KEY));// TODO:如果传入rootNode，则不同级别下会产生重码
			if (nodes != null) {
				if (nodes.length == 1) {
					element = (Element) nodes[0];
				} else if (nodes.length > 1) {
					if (logger.isDebugEnabled()) {
						logger.debug("节点不唯一！" + map);
					}
					continue;
				}
			}

			if (element == null) {
				element = document.createElement(tagName);
			}

			Set<String> set = map.keySet();
			Iterator<String> it = set.iterator();
			while (it.hasNext()) {
				String key = it.next();
				if (isKeyWord(key)) {
					continue;
				}
				String value = map.get(key) != null ? (String) map.get(key) : null;

				element.setAttribute(key, value);
			}

			// 遍历输出内容
			if (map.get(CHILDREN_KEY) != null) {
				createXMLContent(document, element, map);
			}

			if ((rootNode == element)) {
				if (logger.isDebugEnabled()) {
					logger.debug("节点不唯一！" + map);
				}
				continue;
			}
			rootNode.appendChild(element);
		}
	}

	/**
	 * 获取节点
	 * 
	 * @param rootNode
	 *            查找的根节点
	 * @param tagName
	 *            标签
	 * @param idValue
	 *            属性ID值，如果此参数为Null，则返回指定标签的节点数组
	 * @return Node[]
	 */
	private static Node[] findNode(Node rootNode, String tagName, String idValue) {

		Node[] nodes = null;
		List<Node> nodeList = null;
		NodeList nl = null;

		String cName = rootNode.getClass().getSimpleName();
		if ("DeferredElementImpl".equals(cName) || "ElementImpl".equals(cName)) {
			nl = ((Element) rootNode).getElementsByTagName(tagName);
		} else if ("DeferredDocumentImpl".equals(cName) || "DocumentImpl".equals(cName)) {
			nl = ((Document) rootNode).getElementsByTagName(tagName);
		} else {
			logger.error("NodeList is null,未处理的节点类型：" + cName);
			return null;
		}

		if (StringUtils.isEmpty(idValue)) {
			nodes = new Node[nl.getLength()];// 根据标签返回
		} else {
			nodeList = new ArrayList<Node>();// 返回指定标签，指定ID的节点
		}

		if (nl != null) {
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);

				if (StringUtils.isEmpty(idValue)) {
					nodes[i] = node;
				} else {
					String id = null;
					NamedNodeMap nnm = node.getAttributes();
					if (nnm.getLength() > 0) {
						Node key = nnm.getNamedItem(ID_KEY);
						if (key != null) {
							id = key.getNodeValue();
						}
					}
					if (idValue.equals(id)) {
						nodeList.add(node);
					}
				}
			}
		}

		if (nodeList != null) {
			nodes = new Node[nodeList.size()];
			for (int i = 0; i < nodeList.size(); i++) {
				nodes[i] = nodeList.get(i);
			}
		}
		return nodes;
	}

	/**
	 * 新增节点
	 * 
	 * @param filePath
	 *            xml文件路径
	 * @param parentNodeTagName
	 *            父节点标签名
	 * @param parentNodeIdKey
	 *            父节点id
	 * @param datas
	 *            节点数据
	 * @throws ExceptionHandler
	 */
	public static void insertNode(String filePath, String parentNodeTagName, String parentNodeIdKey, List<Map<String, String>> datas) throws ExceptionHandler {

		if (datas.size() == 0) {
			return;
		}

		Document document = getDocument(filePath, true);

		if (document == null) {
			return;
		}

		for (Map<String, String> data : datas) {
			insertNode(document, parentNodeTagName, parentNodeIdKey, data);
		}

		// 将变更写入文件
		transform(document, filePath);

		document = null;
	}

	/**
	 * 新增节点
	 * 
	 * @param document
	 *            XML文档对象
	 * @param parentNodeTagName
	 *            父节点标签名
	 * @param parentNodeIdKey
	 *            父节点id
	 * @param data
	 *            节点数据
	 * @return
	 * @throws ExceptionHandler
	 */
	private static void insertNode(Document document, String parentNodeTagName, String parentNodeIdKey, Map<String, String> data) throws ExceptionHandler {

		// 找到父节点
		Node[] parentNodes = findNode(document, parentNodeTagName, parentNodeIdKey);
		if (parentNodes == null) {
			return;
		}

		for (Node parentNode : parentNodes) {

			String tagName = data.get(TAG_NAME_KEY).toString();
			String idValue = data.get(ID_KEY).toString();

			// 查找子节点
			Node[] children = findNode(parentNode, tagName, idValue);
			if (children != null && children.length > 0) {
				// 存在，更新
				updateNode(document, data);
			} else {
				// 不存在，新增
				Element element = document.createElement(tagName);
				element.setAttribute(ID_KEY, idValue);

				Set<Entry<String, String>> set = data.entrySet();
				Iterator<Entry<String, String>> it = set.iterator();
				while (it.hasNext()) {
					Entry<String, String> entry = it.next();
					if (isKeyWord(entry.getKey().toString())) {
						entry = null;
						continue;// 屏蔽非属性值字段
					}
					element.setAttribute(entry.getKey().toString(), entry.getValue().toString());
					entry = null;
				}
				it = null;
				set = null;

				parentNode.appendChild(element);

				element = null;
			}
			children = null;
		}

	}

	/**
	 * 更新节点
	 * 
	 * @param filePath
	 *            xml文件路径
	 * @param datas
	 *            待更新的数据
	 * @throws ExceptionHandler
	 */
	public static void updateNode(String filePath, List<Map<String, String>> datas) throws ExceptionHandler {

		if (datas.size() == 0) {
			return;
		}

		Document document = getDocument(filePath, true);

		if (document == null) {
			return;
		}

		for (Map<String, String> data : datas) {
			updateNode(document, data);
		}

		// 将变更写入文件
		transform(document, filePath);

		document = null;
	}

	/**
	 * 更新节点
	 * 
	 * @param document
	 *            XML文档对象
	 * @param data
	 *            封装标签名，标签id和属性值的数据，代表一个xml中的一个node
	 * @throws ExceptionHandler
	 */
	private static void updateNode(Document document, Map<String, String> data) throws ExceptionHandler {

		String tagName = data.get(TAG_NAME_KEY).toString();
		String idValue = data.get(ID_KEY).toString();
		Node[] nodes = findNode(document, tagName, idValue);

		if (nodes != null) {

			// 属性键值对
			Set<Entry<String, String>> set = data.entrySet();
			Iterator<Entry<String, String>> it = set.iterator();

			for (Node node : nodes) {
				Element element = (Element) node;
				NamedNodeMap nnm = node.getAttributes();

				// 修改已经存在的属性
				for (int i = 0; i < nnm.getLength(); i++) {
					Node n = nnm.item(i);
					if (data.containsKey(n.getNodeName())) {
						n.setNodeValue(data.get(n.getNodeName()).toString());
					}
					n = null;
				}

				// 添加新的属性
				while (it.hasNext()) {
					Entry<String, String> entry = it.next();
					if (isKeyWord(entry.getKey().toString())) {
						entry = null;
						continue;// 屏蔽非属性值字段
					}
					Node n = nnm.getNamedItem(entry.getKey().toString());
					if (n == null) {
						element.setAttribute(entry.getKey().toString(), entry.getValue().toString());
					}
					n = null;
					entry = null;
				}

				nnm = null;
				element = null;
			}

			nodes = null;
		}

	}

	/**
	 * 删除节点
	 * 
	 * @param filePath
	 *            XML文件路径
	 * @param tagName
	 *            标签名称
	 * @param idValue
	 *            属性ID值，如果此参数值为Null，则删除所有指定的标签节点
	 * @throws ExceptionHandler
	 */
	public static void deleteNode(String filePath, String tagName, String idValue) throws ExceptionHandler {

		Document document = getDocument(filePath, true);

		if (document == null) {
			return;
		}

		Node[] nodes = findNode(document, tagName, idValue);

		if (nodes != null) {
			for (Node node : nodes) {
				node.getParentNode().removeChild(node);
			}
			// 将变更写入文件
			transform(document, filePath);
		}

		nodes = null;

		document = null;

	}

	/**
	 * 将XML文档对象输出到文件
	 * 
	 * @param doc
	 *            Document 对象
	 * @param filePath
	 *            目标文件路径
	 * @throws ExceptionHandler
	 */
	private static void transform(Document doc, String filePath) throws ExceptionHandler {
		DOMSource xmlSource = new DOMSource(doc);

		File file = new File(filePath);
		StreamResult outputTarget = new StreamResult(file);

		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer = null;
		try {
			transformer = tFactory.newTransformer();
		} catch (TransformerConfigurationException e) {
			throw new ExceptionHandler(e);
		}
		tFactory = null;

		transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
		transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

		try {
			transformer.transform(xmlSource, outputTarget);
		} catch (TransformerException e) {
			throw new ExceptionHandler(e);
		} finally {
			transformer = null;
		}
	}

	private static boolean isKeyWord(String key) {
		if (CHILDREN_KEY.equals(key) || P_TAG_NAME_KEY.equals(key) || P_ID_KEY.equals(key) || TAG_NAME_KEY.equals(key) || CHILD_TAG_NAME_KEY.equals(key)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 检测封装的数据是否合法
	 * 
	 * @param data
	 */
	@SuppressWarnings("unused")
	private static void checkData(Map<String, Object> data) {
		// TODO:
	}

}
